package com.chenjim.captureintent

import android.content.ContentValues
import android.content.Intent
import android.net.Uri
import android.os.Build
import android.os.Bundle
import android.os.Environment
import android.provider.MediaStore
import android.util.Log
import android.view.View
import androidx.activity.result.contract.ActivityResultContracts
import androidx.appcompat.app.AppCompatActivity
import androidx.core.content.FileProvider
import com.bumptech.glide.Glide
import java.io.File
import java.io.FileOutputStream
import java.io.InputStream
import java.text.SimpleDateFormat
import java.util.*


class MainActivity : AppCompatActivity() {

    companion object {
        const val TAG = "MainActivity"
        const val CAPTURE_IMG_RQ = 1000
    }

    /**
     * 系统多媒体数据库的uri
     */
    private var mPhotoUri: Uri? = null

    /**
     * [FileProvider]创建的Uri
     */
    private var mVideoUrl: Uri? = null

    private val takeVideo = registerForActivityResult(ActivityResultContracts.CaptureVideo()) { result ->
        if (result == true) {
            Log.d(TAG, "success")
            Glide.with(this@MainActivity).load(mVideoUrl).into(findViewById(R.id.video_view))


            //重新导出Uri视频资源
            contentResolver.openInputStream(mVideoUrl!!)?.let { stream ->
                val outFile = File(getExternalFilesDir(null), "capture.video.mp4")
                writeFile(stream, outFile)
                Log.d(TAG, "new out path:$outFile")
            }
        } else {
            Log.d(TAG, "fail")
        }
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        initClickListener()
    }

    private fun initClickListener() {
        findViewById<View>(R.id.capture_image).setOnClickListener { startTakePhoto() }
        findViewById<View>(R.id.capture_video).setOnClickListener { startTakeVideo() }
    }

    private fun createImageFileName(): String {
        return "${SimpleDateFormat("yyyyMMdd_HHmmss").format(Date())}.jpg"
    }

    private fun createImageFile(): File {
        val time = SimpleDateFormat("yyyyMMdd_HHmmss").format(Date())
        val fileName = "PIC_$time.jpg"
        val path = File(Environment.getExternalStorageDirectory(), "DCIM/Camera")
        if (path.exists()) {
            path.mkdirs()
        }
        val file = File(path, fileName)
        Log.d(TAG, "file path:$file")
        return file
    }


    private fun startTakePhoto() {
        val intent = Intent(MediaStore.ACTION_IMAGE_CAPTURE)
        if (intent.resolveActivity(packageManager) == null) {
            Log.e(TAG, "no activity handle $intent")
            return
        }
        val contentValues = ContentValues(2)

        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.N && false) {
            // 新版本 不一定支持
            contentValues.put(MediaStore.Images.Media.DATA, createImageFile().path)
        } else {
            // 拍完保存在Pictures，这里并不需要写文件权限，后续读取是否需要最好加上
            contentValues.put(MediaStore.Images.Media.DISPLAY_NAME, createImageFileName())
        }

        contentValues.put(MediaStore.Images.Media.MIME_TYPE, "image/jpeg")
        mPhotoUri = contentResolver.insert(
            MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
            contentValues
        )
        intent.putExtra(MediaStore.EXTRA_OUTPUT, mPhotoUri)
        intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
        intent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES)

        startActivityForResult(intent, CAPTURE_IMG_RQ)
    }

    override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
        super.onActivityResult(requestCode, resultCode, data)
        if (requestCode == CAPTURE_IMG_RQ) {
            if (resultCode == RESULT_OK) {
                onImageCaptured()
            } else {
                Log.w(TAG, "on fail:$resultCode")
            }
        }
    }

    private fun onImageCaptured() {
        val projection = arrayOf(
            MediaStore.MediaColumns._ID,
            MediaStore.Images.ImageColumns.ORIENTATION,
            MediaStore.Images.Media.DATA
        )
        val cursor = contentResolver.query(mPhotoUri!!, projection, null, null, null)
        cursor?.run {
            cursor.moveToFirst()
            try {
                val path = cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA))
                Log.d(TAG, "out file path:$path")
                if (File(path).exists()) {
                    Glide.with(this@MainActivity).load(path).into(findViewById(R.id.image_view))

                    //也可以直接用上面的Uri
//                    Glide.with(this@MainActivity).load(mPhotoUri).into(findViewById(R.id.image_view))
                }
            } catch (e: Exception) {
                e.printStackTrace()
            }
            cursor.close()
        }
    }

    private fun startActionTestIntent() {
        startActivity(Intent("com.chenjim.capture"))
    }

    private fun startTakeVideo() {
//        val intent = Intent(MediaStore.ACTION_VIDEO_CAPTURE)
        if (intent.resolveActivity(packageManager) == null) {
            Log.e(TAG, "no activity handle $intent")
            return
        }
        val file = File(filesDir, "${SimpleDateFormat("yyyyMMdd_HHmmss").format(Date())}.mp4")
        mVideoUrl = FileProvider.getUriForFile(this, applicationContext.packageName + ".provider", file)
        takeVideo.launch(mVideoUrl)
    }

    private fun writeFile(inputStream: InputStream, out: File) {
        val parentDir = out.parentFile ?: return
        if (!parentDir.exists()) {
            parentDir.mkdirs()
        }
        try {
            FileOutputStream(out).use { fileOutputStream ->
                val buf = ByteArray(1024)
                var length: Int
                while (inputStream.read(buf).also { length = it } != -1) {
                    fileOutputStream.write(buf, 0, length)
                    fileOutputStream.flush()
                }
                inputStream.close()
                fileOutputStream.flush()
            }
        } catch (e: Exception) {
            Log.e(TAG, out.path + " write fail:" + e)
        }
    }
}